#include "gtest/gtest.h"
#include "spdlog/spdlog.h"
#include "thread_pool.h"

TEST(thread_pool, base) {
    auto runable = []() { spdlog::info("thread_pool thread_pool"); };
    simpleThread::ThreadPool pool;
    pool.execute(runable);

    EXPECT_EQ(pool.getCoreSize(), std::thread::hardware_concurrency());
    EXPECT_EQ(pool.getMaxSize(), std::thread::hardware_concurrency());
}

TEST(thread_pool, execute) {
    volatile int count = 0;
    auto runable = [&count]() {
        count += 1;
        spdlog::info("execute");
    };
    simpleThread::ThreadPool pool(2);
    pool.execute(runable);
    pool.join();

    EXPECT_EQ(count, 1);
}

TEST(thread_pool, submit) {
    volatile int count = 0;
    auto runable = [&count]() {
        spdlog::info("submit");
        count += 1;
        return "ok";
    };
    simpleThread::ThreadPool pool(2);
    auto res = pool.submit(runable);

    EXPECT_EQ(res.get(), "ok");
    EXPECT_EQ(count, 1);
    pool.shutdown();
}

TEST(thread_pool, join) {
    volatile int count = 0;
    auto runable = [&count]() {
        count += 1;
        spdlog::info("join");
    };

    simpleThread::ThreadPool pool(4);
    for (int i = 0; i < 10; ++i) {
        pool.execute(runable);
    }
    pool.join();
    EXPECT_EQ(count, 10);
    EXPECT_TRUE(pool.isClose());

    pool.execute(runable);
    EXPECT_EQ(count, 10);
}

TEST(thread_pool, shutdown) {
    volatile int count = 0;
    auto runable = [&count]() {
        count += 1;
        spdlog::info("join");
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    };

    simpleThread::ThreadPool pool(2);
    for (int i = 0; i < 10; ++i) {
        pool.execute(runable);
    }
    pool.shutdown();
    EXPECT_LT(count, 10);
    EXPECT_TRUE(pool.isClose());

    pool.execute(runable);
    EXPECT_LT(count, 10);
}
